﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.NRefactory.Ast;

namespace Genuilder.Extensibility.TestProject.Gen
{
	public class MagicReflectionVisitor : AbstractAstVisitor
	{
		public override object VisitNamespaceDeclaration(ICSharpCode.NRefactory.Ast.NamespaceDeclaration namespaceDeclaration, object data)
		{
			var parent = (INode)data;
			NamespaceDeclaration ns = new NamespaceDeclaration(namespaceDeclaration.Name);
			base.VisitNamespaceDeclaration(namespaceDeclaration, ns);
			if(ns.Children.Count > 0)
				parent.Children.Add(ns);
			return null;
		}

		public override object VisitCompilationUnit(ICSharpCode.NRefactory.Ast.CompilationUnit compilationUnit, object data)
		{
			CompilationUnit unit = new CompilationUnit();
			base.VisitCompilationUnit(compilationUnit, unit);
			if(unit.Children.Count == 0)
				return null;
			return unit;
		}



		public override object VisitTypeDeclaration(ICSharpCode.NRefactory.Ast.TypeDeclaration typeDeclaration, object data)
		{
			if(!typeDeclaration.Modifier.Has(Modifiers.Partial))
				return null;
			var parent = (INode)data;

			TypeDeclaration type = new TypeDeclaration(Modifiers.Partial | Modifiers.Public, new List<AttributeSection>())
			{
				Name = typeDeclaration.Name
			};


			base.VisitTypeDeclaration(typeDeclaration, type);

			if(type.Children.Count > 0)
				parent.Children.Add(type);
			return null;
		}

		public override object VisitPropertyDeclaration(ICSharpCode.NRefactory.Ast.PropertyDeclaration propertyDeclaration, object data)
		{
			var parent = (INode)data;
			PropertyDeclaration property = new PropertyDeclaration(Modifiers.Public,
				new List<AttributeSection>(),
				propertyDeclaration.Name + "Name",
				new List<ParameterDeclarationExpression>());
			property.TypeReference = new TypeReference("System.String");

			property.GetRegion = new PropertyGetRegion(new BlockStatement()
						{
							Children = new List<INode>()
		                    {
		                        new ReturnStatement(new ICSharpCode.NRefactory.Ast.PrimitiveExpression(propertyDeclaration.Name))
		                    }
						}, new List<AttributeSection>());
			parent.Children.Add(property);
			return null;
		}
	}
}
